package com.snopy.concurrency.demo_base;

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;

/**
  *@des
  *@author:tangxiuliang
  *@date:2020/9/24 10:41
  */
@Slf4j(topic = "Test1")
public class Test1 {


    /**
      *@desciption:
      *wait()方法不会阻塞其他线程
      *@param:
      *@return:
      *@author:tangxiuliang
      *@date:2020/9/24 10:50
      */
    static  final Object lock = new Object();
    public static void main(String[] args) throws InterruptedException{

        Thread thread = new Thread(()->{
            synchronized (lock){
                log.info("current thread:{}",Thread.currentThread().getName());
                try {
                    log.info("waiting.....");
                    lock.wait();
                    log.info("go on.....");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"thread");
        thread.start();
        log.info("main ...");
        Thread.sleep(2000);
        log.info("唤醒");
        synchronized (lock){
            lock.notify();
        }


    }
    /**
      *@desciption:
      *@pararm:
      *@return:
      *@author:tangxiuliang
      *@date:2020/9/28 10:05
      */
    public void testCreateThread()throws ExecutionException, InterruptedException {
        /**
         *创建线程的方式1：直接创建  给线程一个名字是好的实践。不提倡直接创建线程，而是以线程池去创建
         */
        Thread thread2 = new Thread("thread") {
            @Override
            public void run() {
                log.info("create a thread...");
            }
        };
        thread2.start();
        /*
         * 创建线程的方式2：使用Runnable接口
         * */
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                log.info("业务实现");
            }
        };
        Thread thread3 = new Thread(runnable,"thread3");
        thread3.start();

        /*
         * FutureTask 需要线程池驱动
         * */
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        FutureTask task = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                log.info("callable");
                return "Hello Thread";
            }
        });
        Future<?> submit = executorService.submit(task);
        Object o2 = submit.get();
        Object o = task.get();
        log.info("Callable result:{}",o);

        /*
         *lambda表达式简化
         * */
        Thread thread4 = new Thread(()->{
            log.info("this is a thread:{}","thread4");
        },"thread4");
        thread4.start();


        FutureTask<String> task1 = new FutureTask(()->{
            log.info("callable");
            return "Hello Thread";

        });
        Future<?> submit1 = executorService.submit(task1);
        String s = task1.get();
        Object o3 = submit1.get();
        //Object o1 = task1.get();
        log.info("o3 Callable result:{}",o3);
        executorService.shutdown();
    }

    /**
      *@desciption:
      * <p>线程优先级：1-10 默认5</p>
      * Thread.MAX_PRIORITY = 10
      * Thread.NORM_PRIORITY =5
      * Thread.MIN_PRIORITY = 1
      * 当线程数量大于cpu核心数，线程调度时 线程优先级高的有可能会比线程优先级低的  更高概率分配到时间片
      *@pararm:
      *@return:
      *@author:tangxiuliang
      *@date:2020/9/28 10:06
      */
    public void testPriority(){

        Thread thread = new Thread();
        thread.setPriority(Thread.MIN_PRIORITY);
    }
    /**
      *@desciption:
     * <p>wait方法需要获取锁才能调用</p>
      *@pararm:
      *@return:
      *@author:tangxiuliang
      *@date:2020/9/28 10:09
      */

    public void testWait(){

        Thread thread = new Thread(()->{
            try {
                log.info("这能wait？");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"thread");
        thread.start();


        Thread thread1 = new Thread(()->{
            synchronized (this){
                try {
                    log.info("current thread:{}",Thread.currentThread().getName());
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"thread1");
        thread.start();

    }


}
